#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#

from __future__ import with_statement
import sys, os, urllib2, urllib, httplib, time, re, datetime, itertools
pjoin = os.path.join


def replace_py(paths="."):
    r_prd = re.compile("import psycopg2")
    r_ctx = re.compile("except (?P<ret>psycopg2.InternalError)")
    ret = []

    paths = paths.split(",")

    r_prd_replace_func = lambda x: ""
    r_ctx_replace_func = lambda x: "except pgrpc.LogicError"


    def process(root, ofile):
        cur_path = os.path.join(root, onefile)
        f = open(cur_path)
        content = f.read()
        f.close()

        content = r_prd.sub(r_prd_replace_func, content)
        content = r_ctx.sub(r_ctx_replace_func, content)

        f = open(cur_path, "w")
        f.write(content)
        f.close()
        #print cur_path
        #for i in r.finditer(content):
        #    print i.group()

    for path in paths:
        if os.path.isdir(path):
            for root,dirs,files in os.walk(path):
                for onefile in files:
                    if onefile[-2:] != "py":
                        continue
                    process(root, onefile)
        else:
            process(".", path)

FIND_DEF_INTERFACE = "def (?P<ret>[^\(]+)\("
BACKEND_INTEFACE_MATCHER = "(?P<ret>pgrpc\.backend\.[^\(\)\.,]+)"
def find_py_interface(paths=".", parttern=BACKEND_INTEFACE_MATCHER):
    r = re.compile(parttern)
    ret = []

    paths = paths.split(",")

    def getter(root, onefile):
        cur_path = os.path.join(root, onefile)
        f = open(cur_path)
        content = f.read()
        f.close()

        for i in r.finditer(content):
            ret.append(i.group("ret"))


    for path in paths:
        if os.path.isdir(path):
            for root,dirs,files in os.walk(path):
                for onefile in files:
                    if onefile[-2:] != "py":
                        continue
                    getter(root, onefile)
        else:
            getter(".", path)


    ret = sorted(set(ret))
    print "\n".join(ret)

def work_timer(flag="start", message="..."):
    TIME_FORMAT = "%Y-%m-%d %H:%M:%S"
    TIME_MATCHER = "(\d{4}-\d+-\d+ \d+:\d+:\d+)"
    MARK = "耗时: "
    PATH = pjoin("/home", "dreampuf", "work_record.txt")
    try:
        FILE = open(PATH)
    except IOError, ex:
        print ex
        FILE = open(PATH, "w")
        FILE.write("")
        FILE.close()
    FILE = open(PATH, "r")
    data = [i.strip() for i in FILE]
    FILE.close()
    message = [message]
    cur_time = time.time()
    if flag == "start":
        print "START"
        message.insert(0, time.strftime(TIME_FORMAT, time.localtime(cur_time)));
    elif flag == "stop":
        last_time = False
        rgx = re.compile(TIME_MATCHER, re.I)
        for i in data:
            if rgx.search(i):
                last_time = i.strip()
                break
        if not last_time or last_time[-4:] == "STOP":
            return
        last_time = time.mktime(time.strptime(last_time, TIME_FORMAT))
        diff = int((cur_time - last_time) / 60)
        diff_h = int(diff/60)
        if diff_h > 1:
            sdiff = "%dh %dm" % (diff_h, diff-diff_h*60)
        else:
            sdiff = "%d分钟" % (diff)
        tip = "%s%s" % (MARK, sdiff)
        print "STOP"
        print tip
        message.insert(0, tip)
        message.insert(0, "%s %s" % (time.strftime(TIME_FORMAT, time.localtime(cur_time)), "STOP"))
        message.insert(0, "")

    message = message + data
    FILE = open(PATH, 'w')
    FILE.write("\n".join(message))
    FILE.close()

def ukey2int(ukey):
    assert len(ukey)==6,'ukey must has length 6'
    outrange=filter(lambda c:(ord(c)<48) or (ord(c)>57 and ord(c)<97) or (ord(c)>122),ukey)
    assert outrange=='','ukey any char must in 0-9 a-z'
    uint=0
    for c in ukey:
        ord_c=ord(c)
        if ord_c<=57:
            num=ord_c-48
        else:
            num=ord_c-97+10
        uint=uint*36+num
        #print '%s,%d'%(c,num)
    return str(uint).rjust(10, "0")

def ukey2uid(ukey):
    userid=ukey2int(ukey)
    return str(userid).rjust(10,'0')

def int2ukey(uint):
    ukey=''
    for i in range(6):
        uint,remainder=divmod(uint,36)
        if remainder<10:
            ukey=chr(remainder+48)+ukey
        else:
            ukey=chr(remainder+97-10)+ukey
    return ukey

def cc(path='.', filters=None, ori="gbk", tar="utf-8"):
    if filters:
        filters = eval(filters)
    walked = os.walk(path)
    for root,dirs,files in walked:
        for ondir in dirs:
            if filters and not filters(onefile):
                continue
            old = ondir
            ondir = ondir.decode(ori, 'ignore').encode(tar)
            print old, ondir
            os.rename(pjoin(root, old), pjoin(root, ondir))
            map(lambda ((r, d, f)): [r.replace(old, ondir), d, f], walked)
        for onefile in files:
            if filters and not filters(onefile):
                continue
            filename=onefile
            onefile=onefile.decode(ori,'ignore').encode(tar)
            print filename, onefile
            os.rename(pjoin(root, filename), pjoin(root, onefile))

def ccc(path='.', filters=None, ori="gbk", tar="utf-8"):
    if filters:
        filters = eval(filters)
    for root,dirs,files in os.walk(path):
        for onefile in files:
            if filters and not filters(onefile):
                continue
            print "process in %s" % onefile
            rf = open(pjoin(root, onefile), "r")
            wf = open(pjoin(root, onefile), "r")
            data = rf.read()
            data = data.decode(ori,'ignore').encode(tar)
            print data
            wf.write(data)
            rf.close()
            wf.close()
            #filename=onefile
            #onefile=onefile.decode(ori,'ignore').encode(tar)
            #print filename, onefile
            #os.rename(pjoin(root, filename), pjoin(root, onefile))

def post_spam(target, se, timer):
    target = target
    se = se
    timer = int(timer)

    params=urllib.urlencode({
        "ukey":"td58wo",
        "bj_type":"also_ask",
        "obj_id": target,
        "introduction":"",
        })
    headers={
       "Accept":"*/*",
       "Accept-Charset":"UTF-8,*;q=0.5",
       "Accept-Encoding":"gzip,deflate,sdch",
       "Accept-Language":"zh-CN,zh;q=0.8",
       "Connection":"keep-alive",
       "Content-Length":"54",
       "Content-Type":"application/x-www-form-urlencoded",
       "Cookie":"__utmz=253067679.1295706253.52.10.utmcsr=test:8202|utmccn=(referral)|utmcmd=referral|utmcct=/cms_content/article/; gksessionid=886b076827f627f5c3989295fc17fc28; __utma=253067679.1016603714.1292988227.1296146176.1296149624.65; __utmc=253067679; __utmb=253067679.76.10.1296149624",
       "Host":"www.guokr.com",
       "Origin":"http://www.guokr.com",
       "Referer":"http://www.guokr.com/ask/item/%s/?recommend=1"%target,
       "User-Agent":"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.237 Safari/534.10",
       #"X-Requested-With":"XMLHttpRequest",
    }
    website=r"www.guokr.com:80"
    path="/reply/recommend/"
    conn=httplib.HTTPConnection(website)
    for i in xrange(timer):
        conn.request("POST",path,params,headers)
        r=conn.getresponse()
        print r.status,r.reason#,r.content
        data=r.read()
        print data
        conn.close()

    print u"大功告成"


def md(path):
    from markdown import markdown
    f = open(os.path.realpath(path))
    content = f.read()
    print markdown(content, output_format="html4")
    f.close()

test_reqeust_template_codelist = """
:开发人: %(author)s
:Reversion: r%(r_num)s
"""

c_request_template = """
{{{
#!rst
=====================================================
提交测试单
=====================================================

:提交日期: %(now)s
:提交人:  %(author)s
:开发人: %(author)s
:对应项目: *

.. contents:: 目录
.. sectnum::

提交测试内容
=====================

描述
---------------

%(discript)s

解决
--------------

#TODO

提交代码列表
-------------------

%(code_list)s
}}}
"""

def genner_c_test_doc(path=".", start=0, end=0, author="*", func=None):
    popen_instructions = "svn log %s -r%s:%s -v" % (path, start, end)
    data = os.popen(popen_instructions).read()
    if author != "*":
        author = author.split(",")

    if func:
        func = eval(func)
    chinese_re = re.compile('[\x80-\xff]+')
    mt = re.compile("""r(?P<r_num>\\d*) \\| (?P<author>\w*) \\| (?P<data>.+) \\| \\d+ 行
改变的路径:
(?P<files>[\w\W]+?)\n\n(?P<discript>[^-]+?)?\n""")
    code_file = re.compile("""(/[^( \(|:\d+)]+)\\b""", re.I)
    discript = []
    codelist = [["序号", "文件路径", "文件名称", "Reversion", "开发人", "备注       "]]
    n = 1
    onlyfiles = set()

    matchs = mt.finditer(data)
    for i in matchs:
        #print i.groupdict();
        if author != "*" and i.group("author") not in author: #过滤不是指定的编辑人员的测试项目
            continue
        print i.group("author"), author
        print i.group("files")

        if i.group("discript"):
            discript.append(i.group("discript"))
        acode = test_reqeust_template_codelist % {"author": i.group("author"),
                                                  "r_num": i.group("r_num"), }
        files = code_file.findall(i.group("files"))
        files = (set(files) - onlyfiles)
        if not len(files):
            continue
        onlyfiles |= files
        files = list(files)
        files = sorted(files, lambda x,y: os.path.dirname(x) > os.path.dirname(y))

        has_set = False
        for f in files:
            dirname = os.path.dirname(f) + "/"
            filename = os.path.split(f)[1].strip()
            if filename.endswith("_"):
                filename = "%s\\_" % (filename[:1])
            if has_set:
                codelist.append(["", #增加空行.紧密的两行单元格不会进行分行.
                                 "",
                                 "",
                                 "",
                                 "",
                                 ""])
                codelist.append(["",
                                 dirname,
                                 filename,
                                 "",
                                 "",
                                 ""])
            else:
                codelist.append([str(n),
                                 dirname,
                                 filename,
                                 i.group("r_num"),
                                 i.group("author"),
                                 ""])
                n += 1
                has_set = True
    lmax = [0] * 6
    for i in codelist:
        for n, j in enumerate(i):
            lmax[n] = max(len(j.decode("utf-8").encode("gbk")), lmax[n]) #utf-8长度始终为3..gbk才为正常的2

    #head = ["=" * (i+2) for i in lmax]
    #codelist.insert(0, head)
    #codelist.append(head)

    out_table = []
    for ni, i in enumerate(codelist): #每一次提交
        line = []
        for nj, j in enumerate(i): #每一次提交的文件
            if ni == 1:
                line.append("=" * (lmax[nj] + 2))
            elif not i[0].strip(): #没有序号就输出不完整的分割线
                line.append(" " * (lmax[nj] + 2))
            else:
                line.append("-" * (lmax[nj] + 2))
            has_chinese = chinese_re.findall(j)
            chinese_count = sum([len(word.decode("utf-8")) for word in has_chinese])
            codelist[ni][nj] = j.ljust(lmax[nj] + 2 + chinese_count, " ")
        #line.append("+")
        if i[0].strip(): #过滤无效的分割
            out_table.append("+".join(line))
        else:
            codelist[ni] = [i for i in codelist[ni]]
        out_table.append("|".join(codelist[ni]))

    out_table.append("+".join(["-"*(i+2) for i in lmax]))
    out_table = [("+" if i[:3] == "---" or i[:3] == "===" else "|" ) +
                 i +
                 ("+" if i.startswith("--") or i.startswith("==") else "|" ) for n,i in enumerate(out_table)]
    #print "\n".join(out_table)

    codelist = ["    ".join(i) for i in codelist]

    #acode += "\n" + "\n".join(["- %s" % i for i in files])
    #codelist.append(acode)



    print c_request_template % {"discript": "\n".join(["#. %s" % i for i in discript]),
                                "code_list": "\n".join(out_table),#"\n".join(codelist),
                                "now": datetime.datetime.now().strftime("%Y-%m-%d"),
                                "author": ",".join(author) if isinstance(author, list) else "*", }

def email_filter(filename):
    with open(filename) as f:
        ls = list(set([i for i in f.read().split(";") if "@" in i]))
    for i in itertools.izip_longest(*[iter(ls)]*40): #trick http://stackoverflow.com/questions/312443/how-do-you-split-a-list-into-evenly-sized-chunks-in-python
        print "|".join([e for e in i if e is not None])
        print ""
        print ""

COMMEND_MAPPING = {
    "post": post_spam,
    "md": md,
    "cc": cc,
    "ccc": ccc,
    "wt": work_timer,
    "gcd": genner_c_test_doc,
    "fpi": find_py_interface,
    "rp": replace_py,
    "email-filter": email_filter,
}
if __name__ == "__main__":
    val = sys.argv[1] if len(sys.argv) > 1 else None
    if COMMEND_MAPPING.get(val):
        COMMEND_MAPPING[val](*sys.argv[2:])
    elif val:
        print ukey2int(val) if len(val) == 6 else int2ukey(int(val))
    else:
        print "\n".join(COMMEND_MAPPING.keys())
